﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

using Telerik.Sitefinity;
using Telerik.Sitefinity.Configuration;
using Telerik.Sitefinity.Localization.Configuration;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.Modules.News;
using Telerik.Sitefinity.News.Model;
using Telerik.Sitefinity.Services;
using Telerik.Sitefinity.GenericContent.Model;
using Telerik.Sitefinity.Workflow;

namespace Migration.Classes
{
	public static class MigrationNews
	{
		private static NewsManager m_NewsManager;

		static MigrationNews()
		{
			m_NewsManager = NewsManager.GetManager(MigrationSettings.NewsProvider);
		}

		public static void CheckManagers()
		{
			if (m_NewsManager.Provider == null || MigrationSettings.ApplicationRestarted)
			{
				m_NewsManager = NewsManager.GetManager(MigrationSettings.NewsProvider);
			}
		}

		public static void ImportNews(Telerik.Sitefinity.Services.Migration.MigrationGenericContent newsContent)
		{
			CheckManagers();

			var language = newsContent.Language;
            var culture = new CultureInfo(language);
			Guid id = newsContent.Id;
			string name = String.Empty;
			if (newsContent.MetaData.ContainsKey("Title") && newsContent.MetaData["Title"] != null)
				name = newsContent.MetaData["Title"].ToString();

			// Check if the news already exists
			bool addNewLanguage = false;
			NewsItem checkItem = m_NewsManager.GetNewsItems().Where(t => t.Id == id).FirstOrDefault();
			if (checkItem != null)
			{
				if (MigrationCultures.IsMultilingual)
				{
					if (checkItem.AvailableLanguages.Contains(language))
					{
						MigrationLogger.AppendLogMessage(MigrationUtils.GetLocalizableSkipMessage(name, newsContent.Language));
						return;
					}
					else
						addNewLanguage = true;
				}
				else
				{
					MigrationLogger.AppendLogMessage(MigrationUtils.GetLocalizableSkipMessage(name, String.Empty));
					return;
				}
			}

			NewsItem newsItem;
			if (addNewLanguage)
				newsItem = checkItem;
			else
				newsItem = m_NewsManager.CreateNewsItem(id);

			string newsText = String.Empty;
			if (newsContent.Content != null)
				newsText = newsContent.Content.ToString();
			newsText = MigrationUrlRewriter.RewriteAlbumUrls(newsText);

			if (String.IsNullOrEmpty(language))
				newsItem.Content = newsText;
			else
				newsItem.SetString("Content", newsText, language);

			DateTime publicationDate = DateTime.Now;

			foreach (KeyValuePair<string, object> metaData in newsContent.MetaData)
			{
				if (metaData.Value == null)
					continue;

				switch (metaData.Key)
				{
					case "Author":
						if (String.IsNullOrEmpty(language))
							newsItem.Author = metaData.Value.ToString();
						else
							newsItem.Author[language] = metaData.Value.ToString();
						break;
					case "Category":
                        MigrationTaxonomies.AddCategoryToOrganizer(metaData.Value.ToString(), newsItem.Organizer, culture);
						break;
					case "Expiration_Date":
						newsItem.ExpirationDate = DateTime.Parse(metaData.Value.ToString());
						break;
					case "Publication_Date":
						publicationDate = DateTime.Parse(metaData.Value.ToString());
						break;
					case "Source":
						newsItem.SourceName = metaData.Value.ToString();
						break;
					case "Summary":
						if (String.IsNullOrEmpty(language))
							newsItem.Summary = metaData.Value.ToString();
						else
							newsItem.Summary[language] = metaData.Value.ToString();
						break;
					case "Title":
						if (String.IsNullOrEmpty(language))
							newsItem.Title = metaData.Value.ToString();
						else
							newsItem.Title[language] = metaData.Value.ToString();
						break;
					default:
					{
						string metaDataName = metaData.Key;
						var checkField = App.WorkWith().DynamicData().Type(typeof(NewsItem)).Fields().Get().Where(f => f.FieldName == metaDataName).FirstOrDefault();
						if (checkField != null)
						{
							try
							{
								newsItem.SetValue(metaDataName.ToLowerInvariant(), metaData.Value.ToString());
							}
							catch (NullReferenceException) { };
						}
					}
					break;
				}
			}

			newsItem.DateCreated = newsContent.DateCreated;
			newsItem.LastModified = newsContent.DateModified;
			newsItem.Owner = MigrationUsers.DefaultOwner;

			// Add the tags
            MigrationTaxonomies.AddTagsToOrganizer(newsContent.Tags, newsItem.Organizer, culture);

            // Add the URL name
			var urlName = String.Empty;
			if (String.IsNullOrEmpty(language))
				urlName = MigrationUtils.GetUrlName(newsItem.Title);
			else
				urlName = MigrationUtils.GetUrlName(newsItem.Title[language]);

			var checkUrl = m_NewsManager.GetNewsItems().Where(t => t.UrlName == urlName).FirstOrDefault();
            if (checkUrl != null)
                urlName = MigrationUtils.GetUrlName(newsItem.Id.ToString());

			if (String.IsNullOrEmpty(language))
				newsItem.UrlName = urlName;
			else
				newsItem.UrlName[language] = urlName;

			var masterId = newsItem.OriginalContentId;

			m_NewsManager.RecompileItemUrls<NewsItem>(newsItem);

			if (newsItem.Status == ContentLifecycleStatus.Master)
			{
                System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
				m_NewsManager.CheckOut(newsItem);
				masterId = newsItem.Id;
			}
			
			m_NewsManager.SaveChanges();

			var contextBag = new Dictionary<string, string>();
			contextBag.Add("ContentType", newsItem.GetType().FullName);

			WorkflowManager.MessageWorkflow(
				masterId,
				newsItem.GetType(),
				MigrationSettings.NewsProvider,
				"Publish",
				false,
				contextBag);

			// Add the comments
			MigrationComments.AddCommentsToNewsItem(newsItem.Id, newsContent.Comments, language);

			MigrationLogger.AppendLogMessage(MigrationUtils.GetLocalizableImportMessage(name, newsContent.Language));
		}
	}
}
